<template>
  <div class="schedule-management">
    <!-- 页面标题和切换按钮 -->
    <div class="page-header">
      <h2>医生排班管理</h2>
      <el-button type="primary" @click="showHistory = !showHistory">
        {{ showHistory ? '返回排班管理' : '查看历史排班' }}
      </el-button>
    </div>

    <!-- 冲突检测按钮 -->
    <div class="batch-actions" v-if="!showHistory && doctors.length > 0">
      <el-button @click="checkConflicts">检测冲突</el-button>
    </div>

    <!-- 历史排班查看 -->
    <div v-if="showHistory" class="history-view">
      <!-- 历史排班筛选条件 -->
      <div class="history-filter">
        <el-date-picker
          v-model="historyDateRange"
          type="daterange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          @change="filterHistorySchedules"
        />
        <el-select
          v-model="historyDeptFilter"
          placeholder="选择科室"
          clearable
          @change="filterHistorySchedules"
        >
          <el-option
            v-for="dept in departments"
            :key="dept.departmentId"
            :label="dept.departmentName"
            :value="dept.departmentId"
          />
        </el-select>
      </div>

      <!-- 历史排班表格 -->
      <el-table
        :data="paginatedHistorySchedules"
        border
        stripe
        v-loading="historyLoading"
        style="width: 100%; margin-top: 20px;"
      >
        <el-table-column prop="day" label="日期" width="120" align="center" />
        <el-table-column prop="weekday" label="星期" width="100" align="center">
          <template #default="{row}">
            {{ formatWeekday(row.weekday) }}
          </template>
        </el-table-column>
        <el-table-column prop="doc_id" label="医生ID" width="120" align="center" />
        <el-table-column prop="doc_name" label="医生姓名" width="120" align="center" />
        <el-table-column prop="doc_title" label="职称" width="120" align="center" />
        <el-table-column prop="doc_type" label="出诊类型" width="120" align="center">
          <template #default="{row}">
            {{ formatDocType(row.doc_type) }}
          </template>
        </el-table-column>
        <el-table-column label="上午排班" width="180" align="center">
          <template #default="{row}">
            <el-tag v-if="row.amwork" :type="'success'">
              {{ row.amwork }}
            </el-tag>
            <el-tag v-else type="info">未排班</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="下午排班" width="180" align="center">
          <template #default="{row}">
            <el-tag v-if="row.pmwork" :type="'success'">
              {{ row.pmwork }}
            </el-tag>
            <el-tag v-else type="info">未排班</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120" align="center">
          <template #default="{row}">
            <el-button
              type="danger"
              size="small"
              @click="deleteSchedule(row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 历史排班分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="historyPage"
          v-model:page-size="historyPageSize"
          :total="filteredHistorySchedules.length"
          layout="total, prev, pager, next, jumper"
          @current-change="handleHistoryPageChange"
        />
      </div>
    </div>

    <!-- 排班管理主界面 -->
    <div v-else>
      <!-- 周选择器 -->
      <div class="date-range-selector">
        <el-date-picker
          v-model="currentWeek"
          type="week"
          format="YYYY 第 WW 周"
          placeholder="选择周"
          @change="handleWeekChange"
          :disabled-date="disabledDate"
        />
        <el-button-group class="week-nav">
          <el-button @click="prevWeek">上一周</el-button>
          <el-button @click="nextWeek">下一周</el-button>
        </el-button-group>
      </div>

      <!-- 星期选择按钮 -->
      <div class="week-selector">
        <el-button
          v-for="day in weekDays"
          :key="day.value"
          :type="selectedDay === day.value ? 'primary' : ''"
          @click="selectDay(day.value)"
          :disabled="isDateDisabled(day.value)"
        >
          {{ day.label }} ({{ getDateByWeekday(day.value) }})
          <span v-if="isDateDisabled(day.value)" class="disabled-text">(不可排班)</span>
        </el-button>
      </div>

      <!-- 科室筛选 -->
      <div class="filter-container">
        <el-select
          v-model="selectedDepartment"
          placeholder="请选择科室"
          clearable
          @change="handleDepartmentChange"
        >
          <el-option
            v-for="dept in departments"
            :key="dept.departmentId"
            :label="dept.departmentName"
            :value="dept.departmentId"
          />
        </el-select>
      </div>

      <!-- 医生排班表格 -->
      <el-table
        :data="doctors"
        border
        stripe
        v-loading="loading"
        style="width: 100%; margin-top: 20px;"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="doc_id" label="医生ID" width="120" align="center" />
        <el-table-column prop="doc_name" label="医生姓名" width="120" align="center" />
        <el-table-column prop="doc_title" label="职称" width="120" align="center" />
        
        <!-- 出诊类型选择 -->
        <el-table-column label="出诊类型" width="150" align="center">
          <template #default="{row}">
            <el-select
              v-model="row.doc_type"
              placeholder="选择出诊类型"
              clearable
            >
              <el-option label="普通门诊" value="1" />
              <el-option label="专家门诊" value="2" />
              <el-option label="特需门诊" value="3" />
            </el-select>
          </template>
        </el-table-column>
        
        <!-- 上午排班选择 -->
        <el-table-column label="上午排班" width="250" align="center">
          <template #default="{row}">
            <el-select
              v-model="row.amroom"
              placeholder="选择诊室"
              clearable
              style="width: 200px;"
              :disabled="isDateDisabled(selectedDay)"
            >
              <el-option label="不排班" :value="null" />
              <el-option 
                v-for="room in filteredRooms"
                :key="'am'+room.roomId"
                :label="room.roomName"
                :value="room.roomName"
              />
            </el-select>
          </template>
        </el-table-column>
        
        <!-- 下午排班选择 -->
        <el-table-column label="下午排班" width="250" align="center">
          <template #default="{row}">
            <el-select
              v-model="row.pmroom"
              placeholder="选择诊室"
              clearable
              style="width: 200px;"
              :disabled="isDateDisabled(selectedDay)"
            >
              <el-option label="不排班" :value="null" />
              <el-option 
                v-for="room in filteredRooms"
                :key="'pm'+room.roomId"
                :label="room.roomName"
                :value="room.roomName"
              />
            </el-select>
          </template>
        </el-table-column>
        
        <!-- 保存按钮 -->
        <el-table-column label="操作" width="120" align="center">
          <template #default="{row}">
            <el-button
              type="primary"
              size="small"
              @click="saveSchedule(row)"
              :disabled="isDateDisabled(selectedDay)"
            >
              保存
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import axios from 'axios'
import dayjs from 'dayjs'
import isoWeek from 'dayjs/plugin/isoWeek'
import weekOfYear from 'dayjs/plugin/weekOfYear'

// 扩展dayjs功能
dayjs.extend(isoWeek)
dayjs.extend(weekOfYear)

// 响应式数据
const loading = ref(false) // 加载状态
const departments = ref([]) // 科室列表
const doctors = ref([]) // 医生列表
const selectedDepartment = ref('') // 当前选中的科室
const selectedDay = ref('1') // 当前选中的星期（1-7）
const currentWeek = ref(getNextDayMonday()) // 当前周（默认为下一天所在的周一）
const showHistory = ref(false) // 是否显示历史排班
const allSchedules = ref([]) // 所有排班记录
const historyLoading = ref(false) // 历史排班加载状态
const historyDateRange = ref([dayjs().subtract(1, 'month'), dayjs()]) // 历史排班日期范围
const historyDeptFilter = ref('') // 历史排班科室筛选
const historyPage = ref(1) // 历史排班当前页码
const historyPageSize = ref(10) // 历史排班每页条数
const selectedDoctors = ref([]) // 选中的医生（用于批量操作）
const allRooms = ref([]) // 所有诊室数据

// 星期选项
const weekDays = [
  { label: '周一', value: '1' },
  { label: '周二', value: '2' },
  { label: '周三', value: '3' },
  { label: '周四', value: '4' },
  { label: '周五', value: '5' },
  { label: '周六', value: '6' },
  { label: '周日', value: '7' }
]

// 计算属性 - 过滤出当前科室的诊室
const filteredRooms = computed(() => {
  if (!selectedDepartment.value) return []
  return allRooms.value.filter(room => room.departId1 == selectedDepartment.value)
})

// 计算属性 - 分页后的历史排班数据
const paginatedHistorySchedules = computed(() => {
  const start = (historyPage.value - 1) * historyPageSize.value
  const end = start + historyPageSize.value
  return filteredHistorySchedules.value.slice(start, end)
})

// 计算属性 - 筛选后的历史排班数据
const filteredHistorySchedules = computed(() => {
  let result = [...allSchedules.value]
  
  // 按日期范围筛选
  if (historyDateRange.value && historyDateRange.value[0] && historyDateRange.value[1]) {
    const startDate = dayjs(historyDateRange.value[0]).format('YYYY-MM-DD')
    const endDate = dayjs(historyDateRange.value[1]).format('YYYY-MM-DD')
    result = result.filter(schedule => schedule.day >= startDate && schedule.day <= endDate)
  }
  
  // 按科室筛选
  if (historyDeptFilter.value) {
    result = result.filter(schedule => schedule.depart_id1 === historyDeptFilter.value)
  }
  
  return result
})

// 计算属性 - 当前周的日期范围
const currentWeekRange = computed(() => {
  const start = dayjs(currentWeek.value).startOf('isoWeek')
  const end = dayjs(currentWeek.value).endOf('isoWeek')
  return {
    start: start.format('YYYY-MM-DD'),
    end: end.format('YYYY-MM-DD')
  }
})

/**
 * 获取下一天所在的周一
 * @returns {dayjs.Dayjs} 下一天所在的周一
 */
function getNextDayMonday() {
  const tomorrow = dayjs().add(1, 'day')
  return tomorrow.day() === 0 ? tomorrow.subtract(6, 'day') : tomorrow.subtract(tomorrow.day() - 1, 'day')
}

/**
 * 禁用过去的日期
 * @param {Date} date - 待检查的日期
 * @returns {boolean} 是否禁用
 */
const disabledDate = (date) => {
  return dayjs(date).isBefore(dayjs(), 'day')
}

/**
 * 检查日期是否禁用
 * @param {string} weekday - 星期几（1-7）
 * @returns {boolean} 是否禁用
 */
const isDateDisabled = (weekday) => {
  const date = getDateByWeekday(weekday)
  return dayjs(date).isBefore(dayjs(), 'day')
}

/**
 * 根据星期几获取具体日期
 * @param {string} weekday - 星期几（1-7）
 * @returns {string} 格式化后的日期（YYYY-MM-DD）
 */
const getDateByWeekday = (weekday) => {
  const dayIndex = parseInt(weekday) - 1
  const weekStart = dayjs(currentWeek.value).startOf('isoWeek')
  return weekStart.add(dayIndex, 'day').format('YYYY-MM-DD')
}

/**
 * 周选择变化处理
 */
const handleWeekChange = () => {
  fetchDoctorsByDepartment()
}

/**
 * 切换到上一周
 */
const prevWeek = () => {
  currentWeek.value = dayjs(currentWeek.value).subtract(1, 'week')
  fetchDoctorsByDepartment()
}

/**
 * 切换到下一周
 */
const nextWeek = () => {
  currentWeek.value = dayjs(currentWeek.value).add(1, 'week')
  fetchDoctorsByDepartment()
}

/**
 * 选择某一天
 * @param {string} day - 星期几（1-7）
 */
const selectDay = (day) => {
  selectedDay.value = day
  if (selectedDepartment.value) {
    fetchDoctorsByDepartment()
  }
}

/**
 * 获取所有诊室数据
 */
const fetchAllRooms = async () => {
  try {
    const response = await axios.get('http://localhost:8080/hospital5_war/room/findAll')
    allRooms.value = response.data
  } catch (error) {
    console.error('获取诊室数据失败:', error)
    ElMessage.error('获取诊室数据失败')
  }
}

/**
 * 获取所有科室数据
 */
const fetchDepartments = async () => {
  try {
    loading.value = true
    const response = await axios.get('http://localhost:8080/hospital5_war/department/findByLeve?leve=1')
    departments.value = response.data
    // 自动选择第一个科室
    if (departments.value.length > 0) {
      selectedDepartment.value = departments.value[0].departmentId
      fetchDoctorsByDepartment()
    }
  } catch (error) {
    console.error('获取科室列表失败:', error)
    ElMessage.error('获取科室列表失败')
  } finally {
    loading.value = false
  }
}

/**
 * 科室变更处理
 */
const handleDepartmentChange = () => {
  fetchDoctorsByDepartment()
}

/**
 * 获取所有医生数据
 * @returns {Promise<Array>} 医生列表
 */
const fetchAllDoctors = async () => {
  try {
    const response = await axios.get('http://localhost:8080/hospital5_war/doctor/findAll')
    return response.data
  } catch (error) {
    console.error('获取医生列表失败:', error)
    return []
  }
}

/**
 * 获取指定科室的医生列表
 */
const fetchDoctorsByDepartment = async () => {
  if (!selectedDepartment.value) {
    doctors.value = []
    return
  }
  
  try {
    loading.value = true
    const response = await axios.get(
      `http://localhost:8080/hospital5_war/doctor/findByDepartId1?depart_id1=${selectedDepartment.value}`
    )
    
    // 初始化医生数据，添加排班相关字段
    doctors.value = response.data.map(doctor => ({
      ...doctor,
      amroom: null,  // 上午诊室
      pmroom: null,  // 下午诊室
      doc_type: '1'  // 默认普通门诊
    }))
    
    // 检查该医生是否已有排班记录
    await checkExistingSchedules()
  } catch (error) {
    console.error('获取医生列表失败:', error)
    ElMessage.error('获取医生列表失败')
  } finally {
    loading.value = false
  }
}

/**
 * 检查医生是否已有排班记录
 */
const checkExistingSchedules = async () => {
  try {
    const date = getDateByWeekday(selectedDay.value)
    const schedules = allSchedules.value.filter(s => s.day === date)
    
    // 更新医生的排班信息
    doctors.value.forEach(doctor => {
      const existingSchedule = schedules.find(s => s.doc_id === doctor.doc_id)
      
      if (existingSchedule) {
        doctor.amroom = existingSchedule.amwork
        doctor.pmroom = existingSchedule.pmwork
        doctor.doc_type = existingSchedule.doc_type || '1'
      }
    })
  } catch (error) {
    console.error('检查排班失败:', error)
  }
}

/**
 * 获取所有排班记录
 */
const fetchAllSchedules = async () => {
  try {
    historyLoading.value = true
    const response = await axios.get('http://localhost:8080/hospital5_war/doctorWork/findAll')
    const allDoctors = await fetchAllDoctors()
    
    // 处理排班数据，补充医生信息
    allSchedules.value = response.data.map(schedule => {
      const doctor = allDoctors.find(d => d.doc_id === schedule.doc_id)
      
      // 格式化日期
      let formattedDay = schedule.day
      if (formattedDay && !formattedDay.includes('-')) {
        formattedDay = `${dayjs().year()}-${formattedDay}`
      } else if (formattedDay && formattedDay.split('-').length === 2) {
        formattedDay = `${dayjs().year()}-${formattedDay}`
      }
      
      // 验证日期有效性
      if (!dayjs(formattedDay).isValid()) {
        formattedDay = dayjs().format('YYYY-MM-DD')
      } else {
        formattedDay = dayjs(formattedDay).format('YYYY-MM-DD')
      }
      
      return {
        ...schedule,
        ...doctor,
        day: formattedDay,
        doc_name: doctor?.doc_name || '未知医生',
        doc_type: schedule.doc_type || '1'
      }
    })
  } catch (error) {
    console.error('获取排班数据失败:', error)
    ElMessage.error('获取排班数据失败')
  } finally {
    historyLoading.value = false
  }
}

/**
 * 保存排班信息
 * @param {Object} doctor - 医生信息
 */
const saveSchedule = async (doctor) => {
  const date = getDateByWeekday(selectedDay.value)
  
  // 检查是否选择了过去的日期
  if (dayjs(date).isBefore(dayjs(), 'day')) {
    ElMessage.warning('不能为过去的日期排班')
    return
  }
  
  // 检查冲突
  const schedules = allSchedules.value.filter(s => 
    s.day === date && 
    s.doc_id !== doctor.doc_id && // 排除当前医生
    ((s.amwork === doctor.amroom && doctor.amroom) || 
     (s.pmwork === doctor.pmroom && doctor.pmroom))
  )
  
  // 如果发现冲突，提示用户确认
  if (schedules.length > 0) {
    const conflictDoctors = schedules.map(s => s.doc_name).join('、')
    try {
      await ElMessageBox.confirm(
        `发现排班冲突，与医生 ${conflictDoctors} 在同一诊室。是否继续保存？`,
        '排班冲突',
        {
          confirmButtonText: '继续保存',
          cancelButtonText: '取消',
          type: 'warning'
        }
      )
    } catch (error) {
      if (error === 'cancel') return
    }
  }
  
  try {
    loading.value = true
    // 构造请求数据
    const requestData = {
      day: date,
      doc_id: doctor.doc_id,
      amwork: doctor.amroom,
      pmwork: doctor.pmroom,
      create_time: new Date().getTime(),
      weekday: selectedDay.value,
      fee_id: null,
      count_left: null,
      doc_type: doctor.doc_type || '1'
    }

    // 检查是否已有排班记录
    const existingSchedule = allSchedules.value.find(
      s => s.doc_id === doctor.doc_id && s.day === date
    )

    // 根据是否存在记录决定调用新增还是更新接口
    const result = await axios.post(
      existingSchedule 
        ? 'http://localhost:8080/hospital5_war/doctorWork/update'
        : 'http://localhost:8080/hospital5_war/doctorWork/add',
      requestData
    )

    if (result.data) {
      ElMessage.success('排班保存成功')
      // 刷新数据
      await fetchAllSchedules()
      await checkExistingSchedules()
    } else {
      throw new Error('服务器返回空响应')
    }
  } catch (error) {
    console.error('保存失败详情:', error)
    ElMessage.error(`保存失败: ${error.response?.data?.message || error.message}`)
  } finally {
    loading.value = false
  }
}

/**
 * 删除排班记录
 * @param {Object} schedule - 排班记录
 */
const deleteSchedule = async (schedule) => {
  try {
    // 确认删除
    await ElMessageBox.confirm('确定要删除这条排班记录吗?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    
    // 调用删除接口
    const response = await axios.delete(
      `http://localhost:8080/hospital5_war/doctorWork/delete?docId=${schedule.doc_id}&day=${schedule.day}`
    )
    
    if (response.data.success) {
      ElMessage.success('删除成功')
      // 刷新数据
      await fetchAllSchedules()
    } else {
      ElMessage.error(response.data.message || '删除失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除排班失败:', error)
      ElMessage.error('删除排班失败')
    }
  }
}

/**
 * 检查排班冲突
 */
const checkConflicts = () => {
  const date = getDateByWeekday(selectedDay.value)
  
  // 检查是否选择了过去的日期
  if (dayjs(date).isBefore(dayjs(), 'day')) {
    ElMessage.warning('不能为过去的日期排班')
    return
  }
  
  // 获取当天的所有排班记录
  const schedules = allSchedules.value.filter(s => s.day === date)
  
  // 分别检查上午和下午的冲突
  const amConflicts = checkTimeConflicts(schedules, 'amwork')
  const pmConflicts = checkTimeConflicts(schedules, 'pmwork')
  
  // 如果没有冲突
  if (amConflicts.length === 0 && pmConflicts.length === 0) {
    ElMessage.success('未发现排班冲突')
    return
  }
  
  // 构造冲突提示信息
  let message = '发现以下排班冲突：\n'
  if (amConflicts.length > 0) {
    message += `上午冲突：${amConflicts.join('，')}\n`
  }
  if (pmConflicts.length > 0) {
    message += `下午冲突：${pmConflicts.join('，')}`
  }
  
  // 显示冲突信息（不自动关闭）
  ElMessage.warning({
    message: message,
    duration: 0,
    showClose: true
  })
}

/**
 * 检查特定时间段的冲突
 * @param {Array} schedules - 排班记录
 * @param {string} timeField - 时间段（amwork/pmwork）
 * @returns {Array} 冲突信息数组
 */
const checkTimeConflicts = (schedules, timeField) => {
  const roomMap = {}
  const conflicts = []
  
  // 遍历排班记录，检查同一诊室是否有多个医生
  schedules.forEach(s => {
    if (s[timeField]) {
      if (roomMap[s[timeField]]) {
        if (!conflicts.includes(s[timeField])) {
          conflicts.push(s[timeField])
        }
      } else {
        roomMap[s[timeField]] = true
      }
    }
  })
  
  // 返回冲突信息，格式为"诊室名（医生1、医生2）"
  return conflicts.map(room => {
    const doctorsInRoom = schedules
      .filter(s => s[timeField] === room)
      .map(s => s.doc_name)
    return `${room}（${doctorsInRoom.join('、')}）`
  })
}

/**
 * 表格选择变化处理
 * @param {Array} selection - 选中的行
 */
const handleSelectionChange = (selection) => {
  selectedDoctors.value = selection
}

/**
 * 格式化星期显示
 * @param {string} weekday - 星期几（1-7）
 * @returns {string} 格式化后的星期
 */
const formatWeekday = (weekday) => {
  const weekMap = {
    '1': '周一',
    '2': '周二',
    '3': '周三',
    '4': '周四',
    '5': '周五',
    '6': '周六',
    '7': '周日'
  }
  return weekMap[weekday] || weekday
}

/**
 * 格式化出诊类型
 * @param {string} type - 出诊类型（1-3）
 * @returns {string} 格式化后的出诊类型
 */
const formatDocType = (type) => {
  const typeMap = {
    '1': '普通门诊',
    '2': '专家门诊',
    '3': '特需门诊'
  }
  return typeMap[type] || type
}

/**
 * 获取科室名称
 * @param {string} deptId - 科室ID
 * @returns {string} 科室名称
 */
const getDeptName = (deptId) => {
  const dept = departments.value.find(d => d.departmentId === deptId)
  return dept ? dept.departmentName : ''
}

/**
 * 筛选历史排班
 */
const filterHistorySchedules = () => {
  historyPage.value = 1
}

/**
 * 历史排班页码变化处理
 */
const handleHistoryPageChange = () => {}

// 初始化
onMounted(() => {
  fetchDepartments()
  fetchAllSchedules()
  fetchAllRooms().then(() => {
    // 自动选择下一天
    const today = dayjs()
    const tomorrow = today.add(1, 'day')
    const tomorrowWeekday = tomorrow.day() || 7 // 周日返回0，转换为7
    selectedDay.value = tomorrowWeekday.toString()
  })
})
</script>

<style scoped>
.schedule-management {
  padding: 20px;
  background-color: #fff;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.batch-actions {
  margin: 15px 0;
  display: flex;
  gap: 10px;
}

.date-range-selector {
  display: flex;
  align-items: center;
  gap: 15px;
  margin-bottom: 20px;
}

.week-nav {
  margin-left: 15px;
}

.week-selector {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.filter-container {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
}

.history-view {
  margin-top: 20px;
}

.history-filter {
  display: flex;
  gap: 15px;
  margin-bottom: 20px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.disabled-text {
  color: #f56c6c;
  margin-left: 5px;
}
</style>